#coding=utf-8

from PIL import Image,ImageDraw
import yaml
import os
import json
import subprocess

class FileUtil(object):
    
    @classmethod
    def write_content_append(cls,path,content):
        cls.write_content(path,content,"a")
        
    @classmethod
    def write_content(cls, path, content,mode="rw+"):
        with open(path, mode) as f:
            f.write(content+'\n')
            
    @classmethod
    def load_conf(cls, path): # 读取yaml 配置
        with open(path, 'r') as f:
            return yaml.load(f)
        
    @classmethod
    def write_conf(cls, path, content): # 写入yaml 配置
        with open(path, 'w+') as f:
            yaml.dump(content, f)

class ImgUtil(object):
    
    @classmethod
    def tag_img(cls,bound,img_path):
        img = Image.open(img_path)
        img_draw = ImageDraw.Draw(img)
        img_draw.rectangle(bound,outline = "red")
        img.save(img_path)
        img.close()

class CrashUtil(object):
    '''get device crash info by zhangyue'''
    
    @classmethod
    def get_crash_info(cls,d, app, app_path, report_dir):
        serial = d.adb.default_serial
        if d(textContains="无响应").exists:
            d(text="确定").click.wait()
            return cls.check_crash2anr_info(serial, app, app_path, report_dir)
        count=d(textContains="无响应").count
        if count>0:
            d(text="确定").click.wait()
            return cls.check_crash2anr_info(serial, app, app_path, report_dir)
        if d(textContains="掌阅").exists and d(textContains="已停止").exists:
            d(text="确定").click()
            return cls.check_crash2anr_info(serial, app, app_path, report_dir)
        else:
            return cls.check_crash2anr_info(serial, app, app_path, report_dir)
    
    @classmethod
    def check_crash2anr_info(cls, serial, app, app_path, report_dir):
        cshfile = cls._pullCrashFile(serial, app_path, report_dir)#手机自动生成csh文件
        if cshfile:
            return cshfile
        return cls.get_logcat(serial, app, report_dir)
        
        
    @classmethod
    def get_logcat(cls, serial, package_name, report_dir):
        out = raw_cmd("adb -s %s shell logcat -d -v time"%serial).communicate()[0]
        result = []
        error_type = None
        app_flag = False
        for line in out.strip().splitlines():
            if line.strip() == "":
                continue
            if error_type:
                if "E/" in line:
                    result.append(line)
            if error_type is None:
                if 'FATAL EXCEPTION' in line:
                    error_type = "crash"
                    result.append(line)
                elif 'ANR in ' in line and package_name in line:
                    error_type = "anr"
                    app_flag = True
                    result.append(line)
            elif error_type == "crash":
                if package_name in line:
                    app_flag = True     
        if error_type and app_flag:
            return result 
    
    @classmethod       
    def _pullCrashFile(cls, serial, app_path, report_dir):
        crash_path = "/sdcard"+app_path + "/logs"
        cmd_prefix = "adb -s %s "%serial
        cmd=cmd_prefix + 'shell ls %s"|grep csh"'%crash_path
        csh = raw_cmd(cmd).communicate()[0]
        if csh != '':
            
            cmd0=cmd_prefix + "shell ls %s"%crash_path
            out = raw_cmd(cmd0).communicate()[0]
            for line in out.strip().splitlines():
                if  'csh' in line:
                    csh_path=os.path.join(report_dir,'crash_file')
                    cmd1 = cmd_prefix + 'pull %s/%s %s'%(crash_path, line, report_dir)
                    os.system(cmd1)
                    csh_info=cls.isNotDebugCrash(csh_path)
                    if csh_info:
                        return csh_info
            del_cmd = cmd_prefix+'shell "rm -f  %s/*"'%app_path
            os.system(del_cmd)
    
    @classmethod
    def isNotDebugCrash(cls, logFilePath):
        if os.path.exists(logFilePath):
            for file_name in os.listdir(logFilePath):
                if file_name.endswith('csh'):
                    with open(os.path.join(logFilePath,file_name),'rb') as crash_file:
                        crash_info=crash_file.read()
                        index=crash_info.find("DEBUGt_CRASH")
                        if index==-1:
                            crash_info=json.loads(crash_info)['crashInfo'][0]['errorMsg']
                            if len(crash_info)>2048:
                                crash_info=crash_info[:2048]
                            return crash_info

def raw_cmd(cmd_line):
    return subprocess.Popen(cmd_line, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)